package com.it.Service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.it.Mapper.FlightMapper;
import com.it.Service.FlightService;
import com.it.pojo.Flight;
import com.it.pojo.PageBean;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;

@Slf4j
@Service
public class FlightServiceImpl implements FlightService {
    @Autowired
    private FlightMapper flightMapper;

    class AirportGraph {
        private Map<String, List<String>> adjacencyList;

        public AirportGraph(List<Flight> flights) {
            adjacencyList = new HashMap<>();
            for (Flight flight : flights) {
                //adjacencyList.computeIfAbsent(flightMapper.getCity(flight.getDepartAName()), k -> new ArrayList<>()).add(flightMapper.getCity(flight.getArrivalAName()));//键是出发地，值是目的地
                String departCity = flightMapper.getCity(flight.getDepartAName());
                String arrivalCity = flightMapper.getCity(flight.getArrivalAName());

                adjacencyList.computeIfAbsent(departCity, k -> new ArrayList<>());

                List<String> destinations = adjacencyList.get(departCity);
                if (!destinations.contains(arrivalCity)) {
                    destinations.add(arrivalCity);
                }
            }
        }

        public List<String> getNeighbors(String currPlace) {
            return adjacencyList.getOrDefault(currPlace, Collections.emptyList());
        }
    }



    @Override
    public PageBean FSList(String departCity, String arriveCity, Integer peoNumber, LocalDate day, Integer page, Integer pageSize) {
        //1.设置分页参数
        PageHelper.startPage(page,pageSize);

        //2.执行查询
        List<Flight> flightList = flightMapper.FSList(departCity, arriveCity, peoNumber, day);
        Page<Flight> p=(Page<Flight>)flightList;

        //封装PageBean对象
        PageBean pageBean = new PageBean(p.getTotal(), p.getResult());
        return pageBean;
    }

    private static void dfs(AirportGraph graph, String current, String end, Stack<String> currentPath, Set<String> visited, List<List<String>> allRoutes) {
        currentPath.push(current);
        visited.add(current);

        if (current.equals(end)) {
            allRoutes.add(new ArrayList<>(currentPath));
        } else {
            for (String neighbor : graph.getNeighbors(current)) {
                if (!visited.contains(neighbor)) {
                    dfs(graph, neighbor, end, currentPath, visited, allRoutes);
                }
            }
        }

        currentPath.pop();
        visited.remove(current);
    }

    public static int convertToMinutes(String timeString) {
        int totalMinutes = 0;
        int hours = 0;
        int minutes = 0;

        // 检查字符串中是否包含小时部分
        if (timeString.contains("h")) {
            String[] parts = timeString.split("h");
            hours = Integer.parseInt(parts[0]);
            if (parts.length > 1) {
                timeString = parts[1];
            } else {
                timeString = "";
            }
        }

        // 检查字符串中是否包含分钟部分
        if (timeString.contains("min")) {
            String[] parts = timeString.split("min");
            minutes = Integer.parseInt(parts[0]);
        }

        // 计算总分钟数
        totalMinutes = hours * 60 + minutes;
        return totalMinutes;
    }

    private void getAllFlightRoute(List<List<Flight>> arrayF, List<Flight> ResultF, int depth, List<List<Flight>> flightRoute) {
        if(depth == arrayF.size()) {
            flightRoute.add(new ArrayList<>(ResultF));//注意这里需要创建一个新的列表，否则几次递归会叠加造成错误
            return;
        }

        List<Flight> curF = arrayF.get(depth);
        for (Flight flight : curF) {
            ResultF.add(flight);
            getAllFlightRoute(arrayF, ResultF, depth+1,flightRoute);
            ResultF.remove(ResultF.size()-1);
        }
    }

    private void getValidFlightRoute(List<List<Flight>> flightRoute) {
        //涉及到边遍历边修改的情况，可以采用倒序遍历的解决方案
        for(int i=flightRoute.size() -1; i>=0; i--) {
            for(int j=0; j<flightRoute.get(i).size() - 1; j++) {
                int connectTime = convertToMinutes(flightMapper.getConnectionTime(flightRoute.get(i).get(j).getArrivalAName()));
                LocalDateTime arrivalTime = flightRoute.get(i).get(j).getArrivalTime();
                LocalDateTime departTime = flightRoute.get(i).get(j+1).getDepartTime();
                String arrivalName = flightRoute.get(i).get(j).getArrivalAName();
                String departName = flightRoute.get(i).get(j+1).getDepartAName();
                if((!arrivalName.equals(departName)) || (!arrivalTime.isBefore(departTime)) || (Duration.between(arrivalTime,departTime).toMinutes() < connectTime)){
                    flightRoute.remove(i);
                    break;
                }
            }
        }
    }

    @Override
    public PageBean FCList(String departCity, String arriveCity, Integer peoNumber, LocalDate day, Integer page, Integer pageSize) {

        //将当天的飞机航线包装成一个图
        List<Flight> flights = flightMapper.FSList(null,null,peoNumber,day);
        AirportGraph graph = new AirportGraph(flights);

        List<List<String>> allRoutes = new ArrayList<>();
        Stack<String> currentPath = new Stack<>();
        Set<String> visited = new HashSet<>();

        //找出从出发地到目的地所有的路线
        dfs(graph,departCity,arriveCity,currentPath,visited,allRoutes);

        //1.设置分页参数
        PageHelper.startPage(page,pageSize);

        //2.执行查询
        List<List<Flight>> ArrayF = new ArrayList<>();
        List<Flight> ResultF = new ArrayList<>();
        List<List<Flight>> flightRoute = new ArrayList<>();
        for(List<String> route : allRoutes) {
            if(route.size()>2) {
                for (int i = 0; i < route.size() - 1; i++) {
                    ArrayF.add(flightMapper.FSList(route.get(i), route.get(i + 1), peoNumber, day));
                }
            }
        }
        getAllFlightRoute(ArrayF,ResultF,0,flightRoute);
        getValidFlightRoute(flightRoute);


        // 使用 PageInfo 获取分页信息,通过使用 PageInfo 而不是直接进行类型转换，可以避免 ClassCastException 异常，并且能够正确地获取分页信息。
        PageInfo<List<Flight>> pageInfo = new PageInfo<>(flightRoute);
        // 创建 PageBean 对象
        PageBean pageBean = new PageBean(pageInfo.getTotal(), pageInfo.getList());
        return pageBean;

    }

    @Override
    public Flight getFlightById(String fNumber) {
        return flightMapper.getFlightById(fNumber);
    }

    @Override
    public List<String> getTurnCityByName(List<String> aName) {
        return flightMapper.getTurnCityByName(aName);
    }
}
